<?php
/**
 * 限时折扣(全商城)管理
 *
 *
 *
 *
 * @copyright  Copyright (c) 中国追溯
 * @since      File available since Release v1.1
 */

defined('InShopNC') or exit('Access Invalid!');

class p_xianshi_all_goodsModel extends Model {
    
    const XIANSHI_STATE_UNREVIEWED   = 0;    //默认：未审核
    const XIANSHI_STATE_PASS         = 1;    //通过
    const XIANSHI_STATE_FAIL         = 2;    //未通过
    const XIANSHI_STATE_REAPPLY      = 3;    //再次申请
    const XIANSHI_STATE_CLOSE        = 4;    //活动关闭
    const XIANSHI_STATE_DELETE_ADMIN = 5;    //管理员删除
    const XIANSHI_STATE_SOFT_DELETE  = 6;    //软删除

    const   STORE_GOODS_LIMIT      = 5;     //默认活动单一店铺最多可以报名商品数（0：不限制）

    private $mansong_state_array = array(
        self::XIANSHI_STATE_UNREVIEWED   => '未审核',
        self::XIANSHI_STATE_PASS         => '通过',
        self::XIANSHI_STATE_FAIL         => '未通过',
        self::XIANSHI_STATE_REAPPLY      => '再次申请',
        self::XIANSHI_STATE_CLOSE        => '活动关闭',
        self::XIANSHI_STATE_DELETE_ADMIN => '管理员删除',
        self::XIANSHI_STATE_SOFT_DELETE  => '删除'
    );

    private $name_change_state = array(
        'unreviewed'   => 0,
        'pass'         => 1,
        'fail'         => 2,
        'reapply'      => 3,
        'close'        => 4,
        'admin_delete' => 5,
        'soft_delete'  => 6
    );

    public function __construct()
    {
        parent::__construct('p_xianshi_all_goods');
    }

    public function getNameChangeState()
    {
        return $this->name_change_state;
    }

    //获取列表数据
    public function getActivityGoodsListId($ids = array())
    {
        $result = false;
        $ids = (array)$ids;
        if (empty($ids)) {
            $this->setErrorInfo('id不能为空');
            return $result;
        }
        $map = array(
            'xianshi_goods_id' => array('in', $ids)
        );
        $field = 'xianshi_goods_id AS activity_goods_id,goods_id,xianshi_price AS promotion_price,upper_limit';
        $result_data = $this->table('p_xianshi_all_goods')->where($map)->field($field)->select();
        if (empty($result_data)) {
            $this->setErrorInfo('不存在该数据');
            return $result;
        }
        return $result_data;
    }


    /**
     * 更新活动商品数据
     * @param  int    $marketing_activity_id        营销活动编号
     * @param  array  $ids        活动商品id
     * @param  array  $alter_data 修改数据
     * @return int - 成功返回最后更新的id / false - 失败 
     */
    public function updateActivityGoods($marketing_activity_id = 0, $ids = array(), $alter_data = array())
    {
        $result = false;
        $ids = (array)$ids;
        if (empty($ids)) {
            $this->setErrorInfo('请选择要操作的对象');
            return $result;
        }
        // 获取所有所有相关数据，并将其转化为id为主键
        $map['xianshi_goods_id'] = array('in', $ids);
        $correlation_data = $this->table('p_xianshi_all_goods')->field('*')->where($map)->select();
        $change_data = array();
        foreach ($correlation_data as $item) {
            $change_data[$item['xianshi_goods_id']] = $item;
        }
        unset($correlation_data);
        if (empty($change_data) || (count($change_data) !== count($ids))) {
            $this->setErrorInfo('存在违法数据：操作数据中存在，已经删除的对象');
            return false;
        }
        // 允许修改的列
        $allow_field = array('marketing_activity_id' => [], 'marketing_activity_title' => [], 'promotion_price' => ['change_field' => 'xianshi_price'], 'goods_image' => [], 'start_time' => [], 'end_time' => [], 'upper_limit' => [], 'check_state' => ['change_field' => 'xianshi_state'], 'if_recommend' => [], 'activity_goods_sort' => ['change_field' => 'xianshi_goods_sort'], 'fail_cause' => [], 'update_time' => [], 'check_time' => [], 'check_admin_id' => [], 'check_admin_name' => []);
        //排除修改数据中不允许修改的列
        foreach ($alter_data as $keys => $item) {
            if (!isset($allow_field[$keys])) unset($alter_data[$keys]);
            // 判断是否转换列名称 -- 最后判断
            if (isset($allow_field[$keys]['change_field']) && !empty($allow_field[$keys]['change_field'])) {
                $alter_data[$allow_field[$keys]['change_field']] = $alter_data[$keys];
                unset($alter_data[$keys]);
            }
            // 添加上必要字段
            $alter_data['update_time'] = TIMESTAMP;
        }

        //循环修改相应数据
        foreach ($ids as $activity_goods_id) {
            $call_state = true;
            //获得现在的数据
            $field = 'xianshi_goods_id,marketing_activity_id,goods_id,goods_price,start_time,end_time,upper_limit,xianshi_state';
            $original_data = $this->getXianshiGoodsInfo(['xianshi_goods_id' => $activity_goods_id], $field);
            if (empty($original_data)) {
                $this->setErrorInfo('不存在ID为' . $activity_goods_id . '的营销商品');
                return $result;
            }
            //获取修改数据下标，用于判断是否包含敏感列
            $sensitivity_judge = array_keys($alter_data);
            // 敏感列 -- 数据前都会触发特定函数
            $sensitivity_field_front = array('xianshi_price', 'start_time', 'end_time', 'xianshi_state');
            // 是否存在敏感列
            $if_sensitivity = (bool)array_intersect($sensitivity_judge, $sensitivity_field_front);
            if ($if_sensitivity) $call_state = $this->checkAlterAllow($original_data, $alter_data);
            if (!$call_state) {
                $this->setErrorInfo($this->getErrorInfo());
                return $result;
            }
            //修改营销商品数据
            $map = array(
                'xianshi_goods_id' => $activity_goods_id
            );
            $alter_state = $this->table('p_xianshi_all_goods')->where($map)->update($alter_data);
            if (!$alter_state) {
                $this->setErrorInfo('修改营销商品数据失败');
                return $result;
            }
            // 敏感列 -- 数据修改后都会触发特定函数
            $sensitivity_field_later = array('xianshi_price', 'start_time', 'end_time', 'xianshi_state');
            $if_sensitivity = (bool)array_intersect($sensitivity_judge, $sensitivity_field_later);
            if ($if_sensitivity) $call_state = $this->sensitivityAlterCallFunction($original_data, $alter_data);
            if (!$call_state) {
                $this->setErrorInfo($this->getErrorInfo());
                return $result;
            }
        }
        return $activity_goods_id;
    }

    /**
     * 敏感列修改回调函数
     * @param  array  $original_data 原来的数据
     * @param  array  $alter_data    修改的数据
     * @return 
     */
    public function sensitivityAlterCallFunction($original_data = array(), $alter_data = array())
    {
        $result = false;
        //营销商品id
        $activity_goods_id = isset($original_data['xianshi_goods_id']) ? (int)$original_data['xianshi_goods_id'] : 0;
        $original_data = array();
        //获得现在的营销商品数据
        $field = ($item_field = array_keys($original_data)) ? implode(',', $item_field) : '*';
        $now_data = $this->getXianshiGoodsInfo(['xianshi_goods_id' => $activity_goods_id], $field);
        if (empty($now_data)) {
            $this->setErrorInfo('获取不到现在修改后的数据');
            return $result;
        }
        $goods_id = isset($now_data['goods_id']) ? (int)$now_data['goods_id'] : 0;
        if (empty($goods_id)) {
            $this->setErrorInfo('修改后的数据中没有商品id');
            return $result;
        }
        //促销活动id
        $promotion_id = isset($now_data['marketing_activity_id']) ? (int)$now_data['marketing_activity_id'] : '';
        if ($promotion_id === '' ) {
            $this->setErrorInfo('修改后的数据中没有促销活动id');
            return $result;
        }
        //是否更新促销商品价格
        $update_price = false;
        //检查是否促销时间表里是否存在相应数据，若存在直接删除
        $model_p_time = Model('p_time');
        $map_exist = array(
            'goods_id' => $goods_id,
            'promotion_id' => $promotion_id
        );
        $if_exist = $model_p_time->getXianshiAllInfo($map_exist);
        if ($if_exist) {  //存在，删除该记录
            $delete_state = $model_p_time->delXianshiGoodsAll($map_exist);
            if (!$delete_state) {
                $this->setErrorInfo('删除促销活动商品时间失败');
                return $result;
            }
            $update_price = true;
        }
        //检查是否需要新增促销活动商品时间
        if (isset($now_data['xianshi_state']) && ($now_data['xianshi_state'] == self::XIANSHI_STATE_PASS)) {
            //添加价格促销时间
            $add_data_p = array(
                'start_time'      => $now_data['start_time'],
                'end_time'        => $now_data['end_time'],
                'store_id'        => $now_data['store_id'],
                'goods_id'        => $now_data['goods_id'],
                'promotion_id'    => $now_data['marketing_activity_id'],
                'promotion_price' => $now_data['xianshi_price']
            );
            $add_state_p = $model_p_time->addXianshiAll($add_data_p);
            if (!$add_data_p) {
                $this->setErrorInfo('添加价格促销时间失败');
                return $result;
            }
            $update_price = true;
        }
        //是否更新促销价格
        if ($update_price) QueueClient::push('updateGoodsPromotionPriceByGoodsId', $goods_id);

        return true;
    }

    /**
     * 得到操作类型
     * @return array
     */
    public function getMansongStateArray()
    {
        return $this->mansong_state_array;
    }

    /**
     * 增加营销活动商品数据 -- 营销活动必要函数, 调用需开启事务
     * @param array $add_data 必要数据
     */
    public function addActivityGoodsData($add_data = array())
    {
        $result = false;
        //获得组装活动商品数据，校验必要数据
        $assemble_data = $this->assembleActivityGoodsOperateData($add_data);
        if (!$assemble_data) {
            $this->setErrorInfo($this->getErrorInfo());
            return $result;
        }

        //检查是否可以报名
        $apply_allow = $this->checkApplyAllow($assemble_data);
        if ($apply_allow !== true) {
            $this->setErrorInfo($this->getErrorInfo());
            return $result;
        }

        //添加限时折扣(全商城)商品
        $add_state = $this->table('p_xianshi_all_goods')->insert($assemble_data);
        if (!$add_state) {
            $this->setErrorInfo('添加营销活动商品失败');
            return $result;
        }

        //检查商品状态是否为通过
        if (isset($assemble_data['xianshi_state']) && ($assemble_data['xianshi_state'] === self::XIANSHI_STATE_PASS)) {
            //添加价格促销时间
            $model_p_time = Model('p_time');
            $add_data_p = array(
                'start_time'      => $assemble_data['start_time'],
                'end_time'        => $assemble_data['end_time'],
                'store_id'        => $assemble_data['store_id'],
                'goods_id'        => $assemble_data['goods_id'],
                'promotion_id'    => $assemble_data['marketing_activity_id'],
                'promotion_price' => $assemble_data['xianshi_price']
            );
            $add_state_p = $model_p_time->addXianshiAll($add_data_p);
            if (!$add_data_p) {
                $this->setErrorInfo('添加价格促销时间失败');
                return $result;
            }
        }
        $result = $add_state;

        return $result;
    }

    /**
     * 组装活动商品数据 -- 营销活动必要函数
     * @param  array $operate_data 起始必要数据(marketing_activity_id,goods_id,promotion_price,upper_limit,admin_apply,apply_user_id,apply_user_name)
     * @return array - 成功/ false - 失败
     */
    public function assembleActivityGoodsOperateData($operate_data = array())
    {
        $result = false;
        //检查必要数据
        $obj_validate = new Validate();
        $obj_validate->validateparam = array(
            array("input"=>$operate_data['marketing_activity_id'], 'require'=>'true', 'validator'=>'number', 'message'=>'活动编号为必须,且需为integer'),
            array("input"=>$operate_data['goods_id'], 'require'=>'true', 'validator'=>'number', 'message'=>'商品ID为必须,且需为integer'),
            array("input"=>$operate_data['promotion_price'], 'require'=>'true', 'validator'=>'currency', 'message'=>'特惠价格为必须,且需为currencyt'),            
            array("input"=>$operate_data['upper_limit'], 'require'=>'true', 'validator'=>'number', 'message'=>'购买上限为必须,且需为integer'),
            array("input"=>$operate_data['admin_apply'], 'validator'=>'number', 'message'=>'是否是后台操作为必须,且需为integer'),
            array("input"=>$operate_data['apply_user_id'], 'require'=>'true', 'validator'=>'number', 'message'=>'操作人ID为必须,且需为integer'),
            array("input"=>$operate_data['apply_user_name'], 'require'=>'true', 'message'=>'操作人用户名为必须')
        );
        $error = $obj_validate->validate();
        if ($error != ''){
            $this->setErrorInfo($error);
            return $result;
        }

        $model_activity = Model('marketing_activity');
        //获得营销活动数据
        $marketing_activity_id = isset($operate_data['marketing_activity_id']) ? (int)$operate_data['marketing_activity_id'] : 0;
        $field = 'marketing_activity_type,marketing_activity_title,marketing_activity_start_date,marketing_activity_end_date';
        $marketing_activity_data = $model_activity->getActivityOpenDetails($marketing_activity_id, $field);       
        if (empty($marketing_activity_data)) {
            $this->setErrorInfo('不存在该开启的活动');
            return $result;
        }

        //获取商品数据
        $model_goods = Model('goods');
        $goods_id = isset($operate_data['goods_id']) ? (int)$operate_data['goods_id'] : 0;
        $goods_data = $model_goods->getOnlineGoodsInfo($goods_id, 'goods_id,goods_name,store_id,store_name,goods_price,gc_id,goods_image');

        //组装数据
        $assemble = array();  //组装后的数据        
        $if_recommend = isset($operate_data['if_recommend']) ? (int)$operate_data['if_recommend'] : 0;
        $goods_sort = isset($operate_data['goods_sort']) ? (int)$operate_data['goods_sort'] : 0;
        $fail_cause = isset($operate_data['fail_cause']) ? $operate_data['fail_cause'] : '';
        //是否是后台添加
        $admin_add = isset($operate_data['admin_apply']) && ($operate_data['admin_apply'] == 1);
        $check_state = $admin_add ? self::XIANSHI_STATE_PASS : self::XIANSHI_STATE_UNREVIEWED;  //审核状态
        $check_time  = $admin_add ? TIMESTAMP : 0;  //审核时间
        $check_admin_id  = $admin_add ? (int)$operate_data['apply_user_id'] : 0;  //审核人id
        $check_admin_name  = $admin_add ? (string)$operate_data['apply_user_name'] : '';  //审核人用户名
        //找出当前商品历史最低价
        $lowest_price = Model('goods_history')->getGoodsHistoryExtremity($goods_id);
        $lowest_price = isset($lowest_price['min_price']) ? $lowest_price['min_price'] : $goods_data['goods_price'];

        $assemble = array(
                            'marketing_activity_id'    => $marketing_activity_id,
                            'marketing_activity_title' => $marketing_activity_data['marketing_activity_title'],
                            'store_id'                 => $goods_data['store_id'],
                            'store_name'               => $goods_data['store_name'],
                            'goods_id'                 => $goods_id,
                            'goods_name'               => $goods_data['goods_name'],
                            'goods_price'              => $goods_data['goods_price'],
                            'lowest_price'             => $lowest_price,
                            'xianshi_price'            => $operate_data['promotion_price'],
                            'gc_id'                    => $goods_data['gc_id'],
                            'goods_image'              => $goods_data['goods_image'],
                            'start_time'               => $marketing_activity_data['marketing_activity_start_date'],
                            'end_time'                 => $marketing_activity_data['marketing_activity_end_date'],
                            'upper_limit'              => (int)$operate_data['upper_limit'],
                            'xianshi_state'            => $check_state,
                            'if_recommend'             => $if_recommend,
                            'xianshi_goods_sort'       => $goods_sort,
                            'fail_cause'               => $fail_cause,
                            'admin_apply'              => (int)$operate_data['admin_apply'],
                            'apply_user_id'            => (int)$operate_data['apply_user_id'],
                            'apply_user_name'          => (string)$operate_data['apply_user_name'],
                            'create_time'              => TIMESTAMP,
                            'update_time'              => TIMESTAMP,
                            'check_time'               => $check_time,
                            'check_admin_id'           => $check_admin_id,
                            'check_admin_name'         => $check_admin_name
                        );
        return $assemble;
    }

    /**
     * 检查是否可以修改
     * @param  array  $original_data 原来的数据
     * @param  array  $check_data 检查数据
     * @return true - 可以修改 / false - 不可以修改
     */
    public function checkAlterAllow($original_data = array(), $check_data = array())
    {
        static $call_time = array();  //该次事务店铺调用次数，解决事务中，多次调用导致商家报名次数错误的问题
        static $the_apply_goods = array();  //该次事务操作的商品

        $result = false;
        //原来的营销活动id
        $marketing_activity_id = isset($original_data['marketing_activity_id']) ? (int)$original_data['marketing_activity_id'] : 0;

        //判断该营销活动是否存在
        $model_activity = Model('marketing_activity');
        $field = 'marketing_activity_id,marketing_activity_type,marketing_activity_apply_start_date,marketing_activity_apply_end_date,marketing_activity_start_date,marketing_activity_end_date,store_goods_limit';
        $activity_data = $model_activity->getActivityOpenDetails($marketing_activity_id, $field);
        if (empty($activity_data)) {
            $this->setErrorInfo('不存在该开启的活动');
            return $result;
        }

        //营销商品id
        $activity_goods_id = isset($original_data['xianshi_goods_id']) ? (int)$original_data['xianshi_goods_id'] : 0;
        //获取该营销商品信息
        $map_activity_goods['xianshi_goods_id'] = array('eq', (int)$activity_goods_id);
        $activity_goods_data = $this->table('p_xianshi_all_goods')->field('xianshi_goods_id,goods_id,store_id')->where($map_activity_goods)->find();

        if (empty($activity_goods_data)) {
            $this->setErrorInfo('不存在该营销商品');
            return $result;
        }
        $goods_id = isset($activity_goods_data['goods_id']) ? (int)$activity_goods_data['goods_id'] : 0;
        $store_id = isset($activity_goods_data['store_id']) ? (int)$activity_goods_data['store_id'] : 0;

        //判断是否存在该在售商品，且存在库存
        $goods_data = Model('goods')->getOnlineGoodsInfo($goods_id, 'goods_id,goods_price,goods_storage');
        if (empty($goods_data) || ($goods_data['goods_storage'] < 1)) {
            $this->setErrorInfo('不存在该商品：已下架/库存不足');
            return $result;
        }

        //检查促销价是否合理
        if (isset($check_data['xianshi_price']) && ($check_data['xianshi_price'] > $goods_data['goods_price'])) {
            $this->setErrorInfo('限时特惠价格不能大于商品原价');
            return $result;
        }

        //检查该次事务中是否多次操作同一商品 -- 该校验必须在（商品检查是否报名其它促销活动）之前
        if (isset($check_data['goods_id'])) {
            if (in_array($check_data['goods_id'], $the_apply_goods)) {
                $this->setErrorInfo('抱歉，请不要多次操作同一数据');
                return $result;
            }
            //添加$the_apply_goods 的值
            $the_apply_goods[] = $check_data['goods_id'];
        }

        //检查该商品是否已经报名其它促销活动(1:报名多个进行中，且审核通过的限时折扣(全商城) 2：报名多个未结束的促销活动 - p_time表 3：砍价  4：团购 5：拼团)
        $exclude_condition = [
            'promotion_goods_id' => $activity_goods_id,    //促销活动商品id
            'promotion_id'       => $marketing_activity_id, //原来的营销活动编号
            'promotion_type'     => 5   //促销类型2限时折扣,3秒杀,4闪购,5限时折扣(全商城)
        ];
        if (isset($check_data['xianshi_state'])) $exclude_condition['amend_check_state'] = (int)$check_data['xianshi_state'];

        $apply_conflict = $this->checkApplyConflict($goods_id, $exclude_condition);
        if ($apply_conflict !== true) {
            $this->setErrorInfo($this->getErrorInfo());
            return $result;
        }

        //检查商家最多报名商品数   -- 审核状态若为，管理员删除/软删除 不检查该条件
        $allow_check = array(
            self::XIANSHI_STATE_UNREVIEWED,
            self::XIANSHI_STATE_PASS,
            self::XIANSHI_STATE_FAIL,
            self::XIANSHI_STATE_REAPPLY,
            self::XIANSHI_STATE_CLOSE
        );
        if (isset($check_data['xianshi_state']) && in_array($check_data['xianshi_state'], $allow_check)) {
            $store_goods_limit = isset($activity_data['store_goods_limit']) ? (int)$activity_data['store_goods_limit'] : self::STORE_GOODS_LIMIT;
            if ($store_goods_limit !== 0) {  //限制数为0，不检查该条件
                $apply_count = $this->getActivityApplyGoodsCount($marketing_activity_id, $store_id, $exclude_condition);

                // $store_call_time = isset($call_time[$store_id][$marketing_activity_id]) ? $call_time[$store_id][$marketing_activity_id] : 0;    //获取当前商家该活动的调用次数 -- 因为数据库事务隔离级别默认为：可重复读，所以该操作是多余的
                // if ($activity_data['store_goods_limit'] <= $apply_count + $store_call_time) {  //该活动，当前商家已经超限
                //     $this->setErrorInfo('该活动，最多只允许报名' . $activity_data['store_goods_limit'] . '件商品，当前报名为' . ($apply_count + $store_call_time));
                //     return $result;
                // }
                // $store_call_time++; //增加该次事务中商店调用次数
                // $call_time[$store_id][$marketing_activity_id] = $store_call_time;   //存放进静态变量

                if ($activity_data['store_goods_limit'] <= $apply_count) {  //该活动，当前商家已经超限
                    $this->setErrorInfo('该活动，最多只允许报名' . $activity_data['store_goods_limit'] . '件商品，当前报名为' . $apply_count);
                    return $result;
                }

            }
        }
        return true;
    }

    /**
     * 检查报名  -- 营销活动必要函数，需在组装数据后，校验
     * @param  array $check_data 检查数据
     * @return bool  true - 可以报名 / false - 不可以报名
     */
    public function checkApplyAllow($check_data = array())
    {
        static $call_time = array();  //该次事务店铺调用次数，解决事务中，多次调用导致商家报名次数错误的问题
        static $the_apply_goods = array();  //该次事务操作的商品

        $result = false;
        //获取营销活动数据
        $model_activity = Model('marketing_activity');
        $marketing_activity_id = isset($check_data['marketing_activity_id']) ? (int)$check_data['marketing_activity_id'] : 0;
        $field = 'marketing_activity_id,marketing_activity_type,marketing_activity_apply_start_date,marketing_activity_apply_end_date,marketing_activity_start_date,marketing_activity_end_date,store_goods_limit';
        $activity_data = $model_activity->getActivityOpenDetails($marketing_activity_id, $field);  
        if (empty($activity_data)) {
            $this->setErrorInfo('不存在该开启的活动');
            return $result;
        }

        //检查报名时间
        $admin_apply = isset($check_data['admin_apply']) ? (int)$check_data['admin_apply'] : 0;  //是否是后台申请(0:商家申请 / 1: 后台申请)
        if ($admin_apply !== 1) { //如果是后台报名，不限制报名时间
            if (($activity_data['marketing_activity_apply_start_date'] > TIMESTAMP) || ($activity_data['marketing_activity_apply_end_date'] < TIMESTAMP)) {
                $this->setErrorInfo('抱歉，该活动报名时间为' . date('Y-m-d H:i', $activity_data['marketing_activity_apply_start_date']) . '到' . date('Y-m-d H:i', $activity_data['marketing_activity_apply_end_date']));
                return $result;
            }
        }
        
        //判断是否存在该在售商品，且存在库存
        $goods_id = isset($check_data['goods_id']) ? (int)$check_data['goods_id'] : 0;
        $goods_data = Model('goods')->getOnlineGoodsInfo($goods_id, 'goods_id,goods_price,goods_storage');
        if (empty($goods_data) || ($goods_data['goods_storage'] < 1)) {
            $this->setErrorInfo("不存在该ID[{$goods_id}]的商品：已下架/库存不足");
            return $result;
        }

        //检查促销价是否合理
        if ($check_data['xianshi_price'] > $check_data['goods_price']) {
            $this->setErrorInfo('限时折扣(全商城)特惠价格不能大于商品原价');
            return $result;
        }

        //判断该活动是否已结束 -- 活动结束不能报名
        if ($activity_data['marketing_activity_end_date'] < TIMESTAMP) {
            $this->setErrorInfo('活动已结束，不能进行报名');
            return $result;
        }

        //检查该次事务中是否多次操作同一商品 -- 该校验必须在（商品检查是否报名其它促销活动）之前
        if (in_array($check_data['goods_id'], $the_apply_goods)) {
            $this->setErrorInfo('抱歉，请不要多次操作同一数据');
            return $result;
        }
        //添加$the_apply_goods 的值
        $the_apply_goods[] = $check_data['goods_id'];

        //检查该商品是否已经报名其它促销活动(1:报名多个进行中，且审核通过的限时折扣(全商城) 2：报名多个未结束的促销活动 - p_time表 3：砍价  4：团购 5：拼团)
        $apply_conflict = $this->checkApplyConflict($check_data['goods_id']);
        if ($apply_conflict !== true) {
            $this->setErrorInfo($this->getErrorInfo());
            return $result;
        }

        //检查商家最多报名商品数
        $store_goods_limit = isset($activity_data['store_goods_limit']) ? (int)$activity_data['store_goods_limit'] : self::STORE_GOODS_LIMIT;
        if ($store_goods_limit !== 0) {  //限制数为0，不检查该条件
            $store_id = isset($check_data['store_id']) ? (int)$check_data['store_id'] : 0;
            $apply_count = $this->getActivityApplyGoodsCount($marketing_activity_id, $store_id);

            // $store_call_time = isset($call_time[$store_id][$marketing_activity_id]) ? $call_time[$store_id][$marketing_activity_id] : 0;    //获取当前商家该活动的调用次数 -- 因为数据库事务隔离级别默认为：可重复读，所以该操作是多余的
            // if ($activity_data['store_goods_limit'] < $apply_count + $store_call_time) {  //该活动，当前商家已经超限
            //     $this->setErrorInfo('该活动，最多只允许报名' . $activity_data['store_goods_limit'] . '件商品，当前报名为' . ($apply_count + $store_call_time));
            //     return $result;
            // }
            // $store_call_time++; //增加该次事务中商店调用次数
            // $call_time[$store_id][$marketing_activity_id] = $store_call_time;   //存放进静态变量

            if ($activity_data['store_goods_limit'] <= $apply_count) {  //该活动，当前商家已经超限
                $this->setErrorInfo('该活动，最多只允许报名' . $activity_data['store_goods_limit'] . '件商品，当前报名为' . $apply_count);
                return $result;
            }
        }
        return true;
    }


    /**
     * 检查是否报名冲突  -- (1:报名多个进行中，且审核通过的限时折扣(全商城) 2：报名多个未结束的促销活动 - p_time表 3：砍价  4：团购 5：拼团)
     * @param  integer $goods_id 商品id
     * @param  array $exclude_condition 排除数据
        $exclude_condition = [
            'promotion_goods_id' => $promotion_goods_id,    //促销活动商品id
            'promotion_id'       => $marketing_activity_id, //营销活动编号
            'promotion_type'     => 0,   //促销类型2限时折扣,3秒杀,4闪购,5限时折扣(全商城)
            'amend_check_state'  => 2   //修改的审核状态
        ];
     * @return true - 未冲突 / false - 冲突
     */
    public function checkApplyConflict($goods_id = 0, $exclude_condition = array())
    {
        $result = false;
        $goods_id = (int)$goods_id;
        if (!$goods_id) {
            $this->setErrorInfo('检查冲突时，商品id为空');
            return false;
        }

        //校验数据的状态 -- 默认通过
        $amend_check_state = isset($exclude_condition['amend_check_state']) ? (int)$exclude_condition['amend_check_state'] : self::XIANSHI_STATE_PASS;

        //若数据状态是，未通过/管理员删除/软删除 直接返回，无冲突
        if (($amend_check_state === self::XIANSHI_STATE_FAIL) || ($amend_check_state === self::XIANSHI_STATE_DELETE_ADMIN) || ($amend_check_state === self::XIANSHI_STATE_SOFT_DELETE)) return true;

        //只有状态是通过，才检查下面条件，默认检查
        if ($amend_check_state === self::XIANSHI_STATE_PASS) {
            //检查是否存在，报名多个进行中，且审核通过的限时特惠
            $map = array(
                'goods_id' => (int)$goods_id,
                // 'start_time' => array('lt', TIMESTAMP),
                'end_time' => array('gt', TIMESTAMP),
                'xianshi_state' => self::XIANSHI_STATE_PASS
            );
            if (isset($exclude_condition['promotion_goods_id'])) $map['xianshi_goods_id'] = array('neq', (int)$exclude_condition['promotion_goods_id']);
            $conflict_count = $this->getActivityGoodsCount($map);
            if ($conflict_count > 0) {
                $this->setErrorInfo('该商品同时段已经报名限时特惠');
                return false;
            }
        }

        //检查是否报名多个未结束的促销活动 -- 新人特惠不用校验
        $model_p_time = Model('p_time');
        $map = array(
            'goods_id' => (int)$goods_id,
            'end_time' => array('gt', TIMESTAMP)
        );
        //  判断是否存在排除条件
        if (isset($exclude_condition['promotion_id']) && isset($exclude_condition['promotion_type'])) {
            $map['promotion_id'] =  array('neq', (int)$exclude_condition['promotion_id']);
            $map['promotion_type'] =  array('neq', (int)$exclude_condition['promotion_type']);
        }
        $conflict_data = $model_p_time->getInfo($map);
        if ($conflict_data) {
            $promotion_type = $model_p_time->getPromotionType();
            $promotion_name = isset($promotion_type[$conflict_data['promotion_type']]) ? $promotion_type[$conflict_data['promotion_type']] : 'unknown';
            $this->setErrorInfo('该商品存在还未结束的'.$promotion_name.'促销活动');
            return false;
        }

        $model_default = Model();

        // 砍价
        $map_kanjia = array(
            'goods_id' => $goods_id,
            'end_time' => array('gt', TIMESTAMP),
            'kanjia_state'    => 1
        );
        $kanjia_count = $model_default->table('p_kanjia_goods')->where($map_kanjia)->count();
        if ($kanjia_count > 0) {
            $this->setErrorInfo('该商品同时段已经报名砍价');
            return false;
        }

        // 团购
        $map_groupbuy = array(
            'goods_id' => $goods_id,
            'end_time' => array('gt', TIMESTAMP),
            'state'    => 20
        );
        $groupbuy_count = $model_default->table('groupbuy')->where($map_groupbuy)->count();
        if ($groupbuy_count > 0) {
            $this->setErrorInfo('该商品同时段已经报名团购');
            return false;
        }

        // 拼团
        $map_pintuan = array(
            'goods_id' => $goods_id,
            'end_time' => array('gt', TIMESTAMP),
            'pintuan_state'    => 1
        );
        $pintuan_count = $model_default->table('p_pintuan_goods')->where($map_pintuan)->count();
        if ($pintuan_count > 0) {
            $this->setErrorInfo('该商品同时段已经报名拼团');
            return false;
        }

        return true;
    }


    /**
     * 处理商家商品列表
     * @param  integer $marketing_activity_id      营销活动id
     * @param  array  $goods_list     处理商品数据
     * @return array
     */
    public function disposeStoreGoodsSelect($marketing_activity_id, $goods_list = array())
    {
        $goods_list = (array)$goods_list;
        array_walk($goods_list, function(&$item, $keys){
            $apply_conflict = $this->checkApplyConflict($item['goods_id']);
            $item['apply_conflict'] = $apply_conflict;
            $item['apply_conflict_cause'] = ($apply_conflict !== true) ? $this->getErrorInfo() : '';
        });
        return $goods_list;
    }

    /**
     * 得到营销活动已报名商品数量    -- 营销活动必要函数
     * @param  integer $marketing_activity_id 活动编号
     * @param  integer $store_id 店铺id
     * @param  array $exclude_condition 排除数据
        $exclude_condition = [
            'promotion_goods_id' => $promotion_goods_id,    //促销活动商品id
        ];
     * @return int
     */
    public function getActivityApplyGoodsCount($marketing_activity_id = 0, $store_id = 0, $exclude_condition = array())
    {
        $map = array(
            'marketing_activity_id' => (int)$marketing_activity_id,
            'store_id'              => (int)$store_id,
            'xianshi_state'          => array('in', array(self::XIANSHI_STATE_UNREVIEWED, self::XIANSHI_STATE_PASS, self::XIANSHI_STATE_FAIL, self::XIANSHI_STATE_REAPPLY, self::XIANSHI_STATE_CLOSE))
        );
        if (isset($exclude_condition['promotion_goods_id'])) $map['xianshi_goods_id'] = array('neq', (int)$exclude_condition['promotion_goods_id']);
        return $this->getActivityGoodsCount($map);
    }

    /**
     * 获得活动商品数量  -- 营销活动必要函数
     *
     * @param array $condition
     * @param string $field
     * @return int
     */
    public function getActivityGoodsCount($condition) {
        return $this->table('p_xianshi_all_goods')->where($condition)->count();
    }


    /**
     * 通过营销活动编号删除限时折扣(全商城)商品
     * @param  array  $marketing_activity_ids 营销活动编号
     * @return bool
     */
    public function deleteActivityGoods($marketing_activity_ids = array())
    {
        $result = false;
        $marketing_activity_ids = (array)$marketing_activity_ids;
        if (empty($marketing_activity_ids)) {
            $this->setErrorInfo('营销活动编号为空');
            return $result;
        }
        $map = array(
            'marketing_activity_id' => array('in', $marketing_activity_ids)
        );
        $delete_state = $this->delXianshiGoods($map, true);
        if (!$delete_state) {
            $this->setErrorInfo('删除限时折扣(全商城)商品失败');
            return $result;
        }
        return $delete_state;
    }

    /**
     * 某个活动id下是否存在报名的商品
     * @param  int $marketing_activity_id 活动id
     * @return bool true - 存在 / false - 不存在
     */
    public function ifExistGoods($marketing_activity_id = 0)
    {
        $map = array(
            'marketing_activity_id' => (int)$marketing_activity_id
        );
        $if_exist = $this->getXianshiGoodsInfo($map, 'xianshi_goods_id');
        return empty($if_exist) ? false : true;
    }

    /**
     * 某个活动id下是否存在报名通过的商品
     * @param  int $marketing_activity_id 活动id
     * @return bool true - 存在 / false - 不存在
     */
    public function ifExistApplyGoods($marketing_activity_id = 0)
    {
        $map = array(
            'marketing_activity_id' => (int)$marketing_activity_id,
            'xianshi_state' => self::XIANSHI_STATE_PASS,
            'end_time'=>array('gt',time())
        );
        $if_exist = $this->getXianshiGoodsInfo($map, 'xianshi_goods_id');
        return empty($if_exist) ? false : true;
    }

    /**
     * 得到商家是否报名该活动
     * @param  int  $store_id 商家id
     * @param  array  $marketing_ids 活动id
     * @return array
     */
    public function getMerchantApplyState($store_id, $marketing_ids = array())
    {
        $result_data = array();
        if (empty($store_id) || empty($marketing_ids)) return $result_data;

        $field = 'marketing_activity_id,count(xianshi_goods_id) as apply_sum';
        $map = array(
            'marketing_activity_id' => array('in', $marketing_ids),
            'store_id' => (int)$store_id
        );
        $result_data = $this->table('p_xianshi_all_goods')->field($field)->where($map)->group('marketing_activity_id')->select();
        return array_column($result_data, 'apply_sum', 'marketing_activity_id');
    }

    /**
     * 得到活动商品列表
     * @param  array   $condition 条件
     * @param  integer $page      分页
     * @param  integer $limit     条数限制
     * @return array
     */
    public function getActivityGoodsList($condition = array(), $page = 0, $limit = 0)
    {
        $map = array();
        //营销活动编号
        if (!isset($condition['marketing_activity_id'])) return array();
        $map['p_xianshi_all_goods.marketing_activity_id'] = array('eq', (int)$condition['marketing_activity_id']);
        //店铺名称
        if (isset($condition['store_name'])) $map['p_xianshi_all_goods.store_name'] = array('eq', (string)$condition['store_name']);
        //商品名称
        if (isset($condition['goods_name'])) $map['p_xianshi_all_goods.goods_name'] = array('eq', (string)$condition['goods_name']);
        //店铺id
        if (isset($condition['store_id'])) $map['p_xianshi_all_goods.store_id'] = array('eq', (string)$condition['store_id']);

        //软删除状态
        $map['p_xianshi_all_goods.xianshi_state'] = array('neq', self::XIANSHI_STATE_SOFT_DELETE);

        $field = 'p_xianshi_all_goods.xianshi_goods_id AS marketing_activity_detail_id,
                  p_xianshi_all_goods.marketing_activity_id,
                  p_xianshi_all_goods.store_id,
                  store.store_name,
                  store_class.sc_name,
                  p_xianshi_all_goods.goods_id,
                  p_xianshi_all_goods.goods_name,
                  goods.goods_state,
                  p_xianshi_all_goods.goods_price,
                  p_xianshi_all_goods.lowest_price,
                  p_xianshi_all_goods.xianshi_price AS activity_price,
                  p_xianshi_all_goods.goods_image,
                  p_xianshi_all_goods.start_time,
                  p_xianshi_all_goods.end_time,
                  p_xianshi_all_goods.create_time,
                  p_xianshi_all_goods.check_time,
                  p_xianshi_all_goods.upper_limit,
                  p_xianshi_all_goods.xianshi_state AS check_state,
                  p_xianshi_all_goods.xianshi_goods_sort AS activity_goods_sort,
                  p_xianshi_all_goods.fail_cause,
                  p_xianshi_all_goods.check_admin_name';
        $join = 'left,left,left';
        $on = 'p_xianshi_all_goods.goods_id = goods.goods_id,p_xianshi_all_goods.store_id = store.store_id,store.sc_id = store_class.sc_id';
        $result = $this->table('p_xianshi_all_goods,goods,store,store_class')->field($field)->join($join)->on($on)->where($map)->limit($limit)->order('p_xianshi_all_goods.update_time desc')->page($page)->select();
        $goods_state_array = Model('goods')->getGoodsStateArray();
        $check_state_array = $this->getMansongStateArray();

        array_walk($result, function(&$item, $keys)use($goods_state_array, $check_state_array) {
            //拼接设置html
            $operation = '<a class="btn green" href="' . urlShop('goods', 'index', array('goods_id' => $item['goods_id'])) .'"><i class="fa fa-list-alt"></i>查看</a>';
            $operation .= '<span class="btn"><em><i class="fa fa-cog"></i>设置<i class="arrow"></i></em><ul>';
            if ($item['check_state'] != self::XIANSHI_STATE_PASS) {
                $operation .= '<li><a class="confirm-on-click" href="javascript:;" data-href="index.php?act=marketing_activity&op=deal&marketing_activity_id=' . $item['marketing_activity_id'] . '&check_state=' . self::XIANSHI_STATE_PASS . '&marketing_activity_detail_id=' .
                    $item['marketing_activity_detail_id'] .
                    '">通过</a></li>';
            }
            if ($item['check_state'] != self::XIANSHI_STATE_FAIL) {
                $operation .= '<li><a class="confirm-on-click" href="javascript:;" data-href="index.php?act=marketing_activity&op=deal&marketing_activity_id=' . $item['marketing_activity_id'] . '&check_state=' . self::XIANSHI_STATE_FAIL . '&marketing_activity_detail_id=' .
                    $item['marketing_activity_detail_id'] .
                    '">拒绝</a></li>';
            }
            if ($item['check_state'] != self::XIANSHI_STATE_PASS) {
                $operation .= '<li><a class="confirm-on-click" href="javascript:;" data-href="index.php?act=marketing_activity&op=deal&marketing_activity_id=' . $item['marketing_activity_id'] . '&check_state=' . self::XIANSHI_STATE_DELETE_ADMIN . '&marketing_activity_detail_id=' .
                    $item['marketing_activity_detail_id'] .
                    '">删除</a></li>';
            }
            $item['operation'] = $operation;
            $item['goods_url_all'] = urlShop('goods', 'index', array('goods_id' => $item['goods_id']));
            $item['goods_image_all'] = cthumb($item['goods_image'], 60, $item['store_id']);     //商品图片
            $item['goods_state_text'] = isset($goods_state_array[$item['goods_state']]) ? $goods_state_array[$item['goods_state']] : '';    //商品状态
            $item['price_contrast'] = $item['goods_price'] . '/' . $item['lowest_price'] . '/' . $item['activity_price'];   //商品价格/历史最低价/活动价
            $item['price_contrast'] = $item['goods_price'] . '/' . $item['lowest_price'] . '/' . $item['activity_price'] . '/' . $item['upper_limit'];   //商品价格/历史最低价/活动价/限购数量
            $check_time = (isset($item['check_time']) && !empty($item['check_time'])) ? '<br />' . date('Y-m-d H:i:s', $item['check_time']) : '';
            $item['apply_check'] = date('Y-m-d H:i:s', $item['create_time']) . $check_time;     //报名时间/审核时间
            $item['activity_data'] = date('Y-m-d H:i:s', $item['start_time']) . '<br />' . date('Y-m-d H:i:s', $item['end_time']);   //活动时间
            $item['check_state_text'] = isset($check_state_array[$item['check_state']]) ? $check_state_array[$item['check_state']] : '';    //审核状态text
            if ($item['check_state'] == self::XIANSHI_STATE_FAIL) {  //如果审核状态是删除，
                $item['check_state_text_fail_cause'] = $item['check_state_text'] . '<i class="fa fa-question-circle tr_fail_cause" title="' . $item['fail_cause'] . '"></i>';
            }
            $item['activity_state_text'] = ($item['check_state'] == self::XIANSHI_STATE_PASS) ? (($item['start_time'] > TIMESTAMP) ? '待上线' : (($item['end_time'] > TIMESTAMP) ? '进行中' : '已过期')) : $item['check_state_text'];    //活动状态text
        });
        return $result;
    }

    /**
     * 商品列表
     *
     * @param array $condition
     * @param string $field
     * @param int $page
     * @param int $limit
     * @param string $order
     * @return array
     */
    public function getXianshiGoodsList($condition, $field = '*', $page = 0, $limit = 0, $order = 'xianshi_goods_id asc') {
        return $this->table('p_xianshi_all_goods')->field($field)->where($condition)->limit($limit)->order($order)->page($page)->select();
    }

    /**
     * 检查会员是否具有权限购买该商品
     * @param  integer $member_id    会员id
     * @param  array   $xianshi_info  限时折扣商品数据
     * @return true - 超限 / int - 剩余额度   / false - 不限制
     */
    public function checkMemberBuyJurisdiction($member_id = 0, $xianshi_info = array())
    {
        $model_order = Model('order');
        $result = $model_order->getXianshiallUpperLimit($member_id, $xianshi_info);
        return $result;
    }

    /**
     * 审核通过的活动商品
     */
    public function getListDataPass($marketing_activity_ids = array())
    {
        $marketing_activity_ids = (array)$marketing_activity_ids;
        $map = array(
            'xianshi_state' => self::XIANSHI_STATE_PASS
        );
        if ($marketing_activity_ids) $map['marketing_activity_id'] = array('in', $marketing_activity_ids);
        
        $field = 'p_xianshi_all_goods.xianshi_goods_id as activity_goods_id,p_xianshi_all_goods.marketing_activity_id,p_xianshi_all_goods.marketing_activity_title,p_xianshi_all_goods.store_id,p_xianshi_all_goods.store_name,p_xianshi_all_goods.goods_id,p_xianshi_all_goods.goods_name,p_xianshi_all_goods.goods_price,p_xianshi_all_goods.lowest_price,p_xianshi_all_goods.xianshi_price as promotion_price,p_xianshi_all_goods.start_time,p_xianshi_all_goods.end_time,p_xianshi_all_goods.upper_limit,goods.evaluation_good_star,goods.goods_image';
        $on = 'p_xianshi_all_goods.goods_id = goods.goods_id,goods.goods_commonid = goods_common.goods_commonid';
        return $this->table('p_xianshi_all_goods,goods,goods_common')->field($field)->join('left,left')->on($on)->where($map)->order('p_xianshi_all_goods.xianshi_goods_sort ASC')->select();
    }


    /**
     * 得到列表数据
     *
     * @param array $condition
     * @param string $field
     * @param int $page
     * @param int $limit
     * @param string $order
     * @return array
     */
    public function getListData($condition, $field = '*', $page = 0, $limit = 0, $order = 'xianshi_goods_id asc') {
        return $this->table('p_xianshi_all_goods')->field($field)->where($condition)->limit($limit)->order($order)->page($page)->select();
    }   


    /**
     * 获取限时折扣(全商城)商品扩展信息
     * @param array $xianshi_info
     * @return array 扩展限时折扣信息
     *
     */
    public function getXianshiGoodsExtendInfo($xianshi_info) {
        $xianshi_info['goods_url'] = urlShop('goods', 'index', array('goods_id' => $xianshi_info['goods_id']));
        $xianshi_info['image_url'] = cthumb($xianshi_info['goods_image'], 60, $xianshi_info['store_id']);
        $xianshi_info['xianshi_price'] = ncPriceFormat($xianshi_info['xianshi_price']);
        $xianshi_info['xianshi_discount'] = number_format($xianshi_info['xianshi_price'] / $xianshi_info['goods_price'] * 10, 1).'折';
        return $xianshi_info;
    }
    
    /**
     * 获取限时折扣(全商城)商品详细信息
     * @param array $condition
     * @param string $field
     * @return array
     */
    public function getXianshiGoodsInfo($condition, $field = '*') {
        return $this->table('p_xianshi_all_goods')->field($field)->where($condition)->find();
    }

    /**
     * 取得商品信息
     * @param int $goods_id
     * @return array
     */
    public function getXianshiGoodsInfoOpenByGoodsID($goods_id) {
        $goods_info = $this->getXianshiGoodsInfo(array('goods_id'=>$goods_id, 'xianshi_state' => self::XIANSHI_STATE_PASS));
        return $goods_info;
    }

    /**
     * 保存限时折扣(全商城)商品信息
     * @param array $insert
     * @return boolean
     */
    public function addXianshiGoods($insert) {
        return $this->table('p_xianshi_all_goods')->insert($insert);
    }
    
    /**
     * 更新限时折扣(全商城)商品信息
     */
    public function editXianshiGoods($update, $condition) {
        $xianshi_goods_list = $this->getXianshiGoodsList($condition);
        if (empty($xianshi_goods_list)) {
            return true;
        }
        $goodsid_array = array();
        foreach ($xianshi_goods_list as $val) {
            $goodsid_array[] = $val['goods_id'];
        }
        $result = $this->table('xianshi_all_goods')->where(array('goods_id' => array('in', $goodsid_array)))->update($update);
        if ($result) {
            foreach ($goodsid_array as $val) {
                $this->_dGoodsXianshiCache($val);
            }
        }
        return $result;
    }

    /**
     * 删除限时折扣(全商城)商品
     *
     * @param unknown $condition
     * @return boolean
     */
    public function delXianshiGoods($condition, $if_admin = true) {
        $update['xianshi_state'] = ($if_admin === true) ? self::XIANSHI_STATE_DELETE_ADMIN : self::XIANSHI_STATE_SOFT_DELETE;
        return $this->table('p_xianshi_all_goods')->where($condition)->update($update);
    }

    /**
     * 读取商品限时折扣(全商城)缓存
     * @param int $goods_id
     * @return array/bool
     */
    private function _rGoodsXianshiCache($goods_id) {
        return rcache($goods_id, 'goods_xianshi_all');
    }
    
    /**
     * 写入商品限时折扣(全商城)缓存
     * @param int $goods_id
     * @param array $info
     * @return boolean
     */
    private function _wGoodsXianshiCache($goods_id, $info) {
        return wcache($goods_id, $info, 'goods_xianshi_all');
    }
    
    /**
     * 删除商品限时折扣(全商城)缓存
     * @param int $goods_id
     * @return boolean
     */
    private function _dGoodsXianshiCache($goods_id) {
        return dcache($goods_id, 'goods_xianshi_all');
    }

    /**
     * 用来校验实例的模型是否正确
     * @return bool
     */
    public function _correctModel()
    {
        return true;
    }

}
